﻿using CodePrinter.Util;
using HZH_Controls.Forms;
using Microsoft.Win32;
using PdfSharp;
using PdfSharp.Drawing;
using PdfSharp.Pdf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;

namespace CodePrinter
{
	public partial class Form1 : FrmBase
	{

		static Font xF = new Font(new FontFamily("微软雅黑"), 16);
		Random ran = new Random();
		public Form1()
		{
			CodeUtil.instance.InitCode();
			InitializeComponent();
			SystemEvents.SessionEnding += SystemEvents_SessionEnding;
		}

		private void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e)
		{
			// 在此执行你的代码，例如保存数据、清理资源等
			CodeUtil.instance.SaveCode();
			MessageBox.Show("计算机即将关闭，执行一些操作...");

			// 如果你希望取消关闭操作，可以通过 e.Reason 属性来判断关闭的原因
			if (e.Reason == SessionEndReasons.SystemShutdown)
			 {

			//     e.Cancel = true;
			 }
		}

		// 其他窗体事件和方法...

		
			
		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void Form1_FormClosing(object sender, FormClosingEventArgs e)
		{
			CodeUtil.instance.SaveCode();
			// 在窗体关闭时移除事件处理程序，避免内存泄漏
			SystemEvents.SessionEnding -= SystemEvents_SessionEnding;

		}
		private void ucBtnExt2_BtnClick(object sender, EventArgs e)
		{
			FrmWaiting waiting = new FrmWaiting();
			waiting.ShowForm();
			Task.Run(() =>
			{
				CreatePdf((int)ucNumTextBox_codenum.Num, textBoxEx_Filename.Text + ".pdf");
				this.Invoke(new Action(() =>
				{
					waiting.Close();
					FrmTips.ShowTipsSuccess(this, "生成成功");

				}));
			});
		}

		public string GetRange(Func<Random, int, string> funv, Random random, int length)
		{

			while (true)
			{
				string str = funv.Invoke(random, length);
				int much = 0;
				for (int i = 0; i < length - 1; i++)
				{
					if (much == 3)
					{
						break;
					}
					if (str[i] == str[i + 1])
					{
						much++;
					}
					else
					{
						much = 0;
					}
				}
				if (much == 3)
				{
					continue;
				}
				else
				{
					return str;
				}
			}
		}
		public string GetRange(Func<int, Func<string>[], Func<string> , string> funv, int length, Func<string>[] Action, Func<string> outf = null)
		{

			while (true)
			{
				string str = funv.Invoke(length,Action, outf);
				int much = 0;
				for (int i = 0; i < length - 1; i++)
				{
					if (much == 3)
					{
						break;
					}
					if (str[i] == str[i + 1])
					{
						much++;
					}
					else
					{
						much = 0;
					}
				}
				if (much == 3)
				{
					continue;
				}
				else
				{
					return str;
				}
			}
		}

		public string RangeA7358(Random random, int length)
		{
			const string digits = "A7358";
			return new string(Enumerable.Repeat(digits, length)
			  .Select(s => s[random.Next(s.Length)]).ToArray());

		}
		public string RangeEFGLZ(Random random, int length)
		{
			const string digits = "EFGLZ";
			return new string(Enumerable.Repeat(digits, length)
			  .Select(s => s[random.Next(s.Length)]).ToArray());

		}
		public string GennerCode()
		{

			StringBuilder stringBuilder = new StringBuilder();
			var i1 = ran.Next(4);
			stringBuilder.Append(GetRange(ranGet,i1, new Func<string>[] { () => "G20", () => "G10", () => "G21", () => "G32", }));
			stringBuilder.Append(GetRange(RangeA7358,ran,1));
			if (radioButtonblue.Checked)
			{
				stringBuilder.Append("04");
			}
			else if (radioButtonred.Checked)
			{
				stringBuilder.Append("02");

			}
			else if (radioButtonwhite.Checked)
			{
				stringBuilder.Append("00");

			}
			var i2 = ran.Next(2);
			string str = ranGet(i2, new Func<string>[] {
						() => {
				
						return  RandomString(ran, 1);
					},() => {
					
						return  RandomNumbers(ran, 1);
					},  });
			stringBuilder.Append(str);
			i2 = ran.Next(2);
			str = ranGet(i2, new Func<string>[] {
						() => {

						return  RandomString(ran, 1);
					},() => {

						return  RandomNumbers(ran, 1);
					},  });
			stringBuilder.Append(str);

			stringBuilder.Append(RangeEFGLZ(ran,1));
			string str1 = ranGet(i2, new Func<string>[] {
						() => {

						return  "102";
					},() => {

						return  "103";
					},  });
			stringBuilder.Append(str1);
			stringBuilder.Append(GetRange(RandomRandomNumbers, ran, 5));
			return stringBuilder.ToString();
		}

		void CreatePdf(int numCodes, string pdfFileName)
		{
			PdfDocument document = new PdfDocument();
			int numPages = numCodes ;

			
			// 计算每个条码的宽度和高度
			double barcodeWidth = 11; // 一页最多三列
			double barcodeHeight = 11;
			///第几页
			///
			PdfDocument doc = new PdfDocument("/Template/tem.pdf");
			for (int i = 0; i < numPages; i++)
			{
				
				PdfPage page = document.AddPage((PdfPage)doc.Pages[0].Clone() );


				XGraphics gfx = XGraphics.FromPdfPage(page);
				///打印到第几行
				for (int j = 0; j < 3; j++)
				{
					///打印到第几列
					for (int k = 0; k < Math.Min(numCodes, 3); k++)
					{
						int codeIndex = i * 9 + j * 3 + k;

						if (codeIndex < numCodes)
						{
							double x = k * barcodeWidth;
							double y = j * barcodeHeight;
							string code = "";
							int count = 10000;
							while (!CodeUtil.instance.AddCode(code = GennerCode()))
							{
								if (count-- < 0)
								{
									this.Invoke(new Action(() => { 
										FrmTips.ShowTipsError(this,"条码快满了哦，请重置条码");
									}));
									return;
								}
							}
							string barcodeFileName = $"barcode_{codeIndex}.png";
							string qrcodeFileName = $"qrcode_{codeIndex}.png";

							GenerateQRCode(code, qrcodeFileName);

							XImage barcodeImage = XImage.FromFile(qrcodeFileName);
							gfx.DrawImage(barcodeImage, x, y, barcodeWidth, barcodeHeight - 30);
							barcodeImage.Dispose();
							//XImage qrcodeImage = XImage.FromFile(qrcodeFileName);
							XSize xs = gfx.MeasureString(code, new XFont("Arial", 12));
							gfx.DrawString(code, new XFont("Arial", 12), new XSolidBrush(XColor.FromArgb(255, 0, 0, 0)), new XPoint(x + (barcodeWidth - xs.Width) / 2, y + barcodeHeight - 30));

							// 清理生成的图片文件
							//File.Delete(barcodeFileName);
							File.Delete(qrcodeFileName);
						}
					}
				}
			}

			// 保存PDF文件
			document.Save(pdfFileName);

		}


		// 生成二维码
		static void GenerateQRCode(string data, string fileName)
		{
			QRCoder.QRCodeGenerator qrGenerator = new QRCoder.QRCodeGenerator();
			QRCoder.QRCodeData qrCodeData = qrGenerator.CreateQrCode(data, QRCoder.QRCodeGenerator.ECCLevel.Q);
			QRCoder.QRCode qrCode = new QRCoder.QRCode(qrCodeData);
			System.Drawing.Bitmap qrCodeImage = qrCode.GetGraphic(20);

			qrCodeImage.Save(fileName);
		}

		// 生成指定长度的随机大写字母
		static string RandomString(Random random, int length)
		{
			const string chars = "ABCDEFGHJKLMNPQRSTUVWXYZ";
			return new string(Enumerable.Repeat(chars, length)
			  .Select(s => s[random.Next(s.Length)]).ToArray());
		}

		// 生成指定长度的随机数字
		static string RandomNumbers(Random random, int length)
		{
			const string digits = "0123456789";
			return new string(Enumerable.Repeat(digits, length)
			  .Select(s => s[random.Next(s.Length)]).ToArray());
		}
		/// <summary>
		/// 生成n个不同的数字
		/// </summary>
		/// <param name="random"></param>
		/// <param name="length"></param>
		/// <returns></returns>
		static string RandomRandomNumbers(Random random, int length)
		{
			string x = "";
			string digits = "0123456789";
			for (int i = 0; i < length && 10 > length; i++)
			{
				int ind = random.Next(digits.Length);
				x += digits[ind];
				digits = digits.Remove(ind, 1);
			}
			return x;
		}
		public string ranGet(int i, Func<string>[] Action, Func<string> outf = null)
		{
			try
			{
				if (Action.Length >= i + 1)
				{
					return Action[i].Invoke();

				}
				else
				{
					return outf.Invoke();

				}
			}
			catch (Exception)
			{

				return outf.Invoke();
			}

		}

		private void ucNumTextBox2_NumChanged(object sender, EventArgs e)
		{

		}

		private void label2_Click(object sender, EventArgs e)
		{

		}

		private void ucBtnExt3_BtnClick(object sender, EventArgs e)
		{
			this.Close();
		}

		private void ucNumTextBox_page_NumChanged(object sender, EventArgs e)
		{

		}
		/// <summary>
		/// 重置条码
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void ucBtnExt1_BtnClick(object sender, EventArgs e)
		{
			;
			;
			if (FrmDialog.ShowDialog(this,"确认重置已生成的条码","警告",true)== DialogResult.OK)
			{
				//重置
				CodeUtil.instance.Clear();
				FrmTips.ShowTipsSuccess(this,"重置成功");
			}
		}
	}
}
